package com.krtech.wecard.module.sys.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.krtech.wecard.config.LakerConfig;
import com.krtech.wecard.framework.exception.BusinessException;
import com.krtech.wecard.framework.ext.mybatis.UserDataPower;
import com.krtech.wecard.framework.model.CommRes;
import com.krtech.wecard.framework.utils.LoginUtil;
import com.krtech.wecard.module.pub.entity.ApplicationManagement;
import com.krtech.wecard.module.pub.entity.CardIdentityRelationInfo;
import com.krtech.wecard.module.pub.entity.CardInfoUser;
import com.krtech.wecard.module.pub.entity.ClassificationInfo;
import com.krtech.wecard.module.pub.service.CardIdentityRelationInfoService;
import com.krtech.wecard.module.pub.service.CardInfoUserService;
import com.krtech.wecard.module.pub.service.ClassificationInfoService;
import com.krtech.wecard.module.sys.entity.SysDept;
import com.krtech.wecard.module.sys.entity.SysSchoolInfo;
import com.krtech.wecard.module.sys.entity.SysUser;
import com.krtech.wecard.module.sys.entity.SysUserRole;
import com.krtech.wecard.module.sys.mapper.SysDeptMapper;
import com.krtech.wecard.module.sys.mapper.SysUserMapper;
import com.krtech.wecard.module.sys.pojo.SysUserSyncVo;
import com.krtech.wecard.module.sys.pojo.SysUserVo;
import com.krtech.wecard.module.sys.pojo.UserDto;
import com.krtech.wecard.module.sys.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author laker
 * @since 2021-08-05
 */
@Service
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements SysUserService {
    @Autowired
    SysDeptMapper deptMapper;

    @Autowired
    private SysDeptService deptService;

    @Autowired
    ISysRoleService sysRoleService;
    @Autowired
    ISysUserRoleService sysUserRoleService;
    @Autowired
    LakerConfig lakerConfig;


    @Autowired
    private SysSchoolInfoService schoolInfoService;

    @Autowired
    private SysUserOperateLogService userOperateLogService;

    @Autowired
    private SysKeyValueService keyValueService;

    @Autowired
    private CardInfoUserService cardInfoUserService;

    @Autowired
    private CardIdentityRelationInfoService cardIdentityRelationInfoService;

    @Autowired
    private SysUserMapper sysUserMapper;




    @Override
    public SysUser getUserAndDeptById(Long userId) {
        SysUser user = this.getById(userId);
        if (user == null) {
            return null;
        }
//        SysDept sysDept = deptMapper.selectById(user.getDeptId());
//        user.setDeptId(sysDept.getDeptId());
        return user;
    }

    @Override
    public List<UserDataPower> getUserDataPowers(Long userId) {
        return this.getBaseMapper().getUserDataPowers(userId);
    }

    @Override
    public Page<SysUserVo> pageComplexAll(Page<SysUser> page, UserDto userDto) {
        return sysUserMapper.pageComplexAll(page,userDto);
    }

    @Override
    public int updateBatch(List<SysUser> list) {
        return baseMapper.updateBatch(list);
    }

    @Override
    public int batchInsert(List<SysUser> list) {
        return baseMapper.batchInsert(list);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public CommRes saveOrUpdate(SysUserVo param) {

        if (param.getDeptId() == null && StrUtil.isEmpty(param.getDeptCode())) {
            throw new BusinessException(param.getPhone()+ "请选择部门");
        }

        if (StrUtil.isNotEmpty(param.getDeptCode())){
            //通过deptcode查询deptid
            SysDept sysDept = deptService.getOne(new QueryWrapper<SysDept>().eq(SysDept.COL_CODE, param.getDeptCode()));
            param.setDeptId(sysDept.getDeptId());
            param.setDeptName(sysDept.getDeptName());
        }

        if (StrUtil.isEmpty(param.getPhone())){
            throw new BusinessException("必填参数电话号码不能为空");
        }

        //判断是否有userCode
        int judge = 0;
        SysUser updateUser = null;
        if (StrUtil.isNotEmpty(param.getUserCode())){
            judge = this.count(new QueryWrapper<SysUser>()
                    .eq(SysUser.COL_USER_CODE, param.getUserCode())
                    .eq(SysUser.COL_DEL_FLAG,0));

            updateUser = this.getOne(new QueryWrapper<SysUser>()
                    .eq(SysUser.COL_USER_CODE, param.getUserCode())
                    .eq(SysUser.COL_DEL_FLAG,0));
        }else {
            judge = this.count(new QueryWrapper<SysUser>()
                    .eq(SysUser.COL_PHONE, param.getPhone())
                    .eq(SysUser.COL_DEL_FLAG,0));

            updateUser = this.getOne(new QueryWrapper<SysUser>()
                    .eq(SysUser.COL_PHONE, param.getPhone())
                    .eq(SysUser.COL_DEL_FLAG,0));
        }


        if (judge <= 0) {
            // 只有超级管理员才能创建用户
//            if (!LoginUtil.judgeAdmin()) {
//                return CommRes.error("403", "只有超级管理员才能创建用户!");
//            }

            //判断电话是否已经创建了账号了
//            int judge = sysUserService.count(new QueryWrapper<SysUser>()
//                    .eq(SysUser.COL_USER_NAME, param.getPhone())
//                    .eq(SysUser.COL_DEL_FLAG,0));
//
//            if (judge > 0){
//                throw new BusinessException("该电话号码已经创建为了用户");
//            }

            String password = param.getPassword();
            param.setPassword(SecureUtil.sha256(password));
            param.setCreateTime(new Date());
            if (StrUtil.isEmpty(param.getUserCode())){
                param.setUserCode(param.getPhone());
            }

            if (StrUtil.isEmpty(param.getUserName())){
                param.setUserName(param.getPhone());
            }

            //查询出当前学校的信息
            List<SysSchoolInfo> schoolInfoList = schoolInfoService.list(new QueryWrapper<SysSchoolInfo>().eq(SysSchoolInfo.COL_DEL_FLAG,0));
            if (schoolInfoList.size() > 0){
                SysSchoolInfo schoolInfo = schoolInfoList.get(0);
                param.setSchoolId(schoolInfo.getId());
                param.setSchoolName(schoolInfo.getName());
                param.setSchoolCode(schoolInfo.getSchoolCode());
            }

            this.save(param);
            if (param.getRoleList().size() > 0) {
                List<Integer> roleIdList = param.getRoleList().stream().map(one -> Integer.parseInt(one.getRoleId().toString())).collect(Collectors.toList());
                this.saveUserRole(param.getUserId(), roleIdList);
            }
        } else {

            param.setUserId(updateUser.getUserId());

            if (StrUtil.isNotEmpty(param.getPassword())){
                String password = param.getPassword();
                param.setPassword(SecureUtil.sha256(password));
            }

//            userOperateLogService.saveUserLog(param);


            // 特殊处理电话号码不为空的情况
            if (!updateUser.getPhone().equals(param.getPhone())){
                //当其不相等的时候，将手机号码换为新的手机号码的同时，并且去掉原号的微信小程序openId
                param.setMipOpenId("");
                param.setOpenIdAdmin("");
                param.setPublicOpenId("");
            }

            //todo 死循环 good
            this.updateById(param);
            if (param.getRoleList() != null && param.getRoleList().size() > 0) {
                List<Integer> roleIdList = param.getRoleList().stream().map(one -> Integer.parseInt(one.getRoleId().toString())).collect(Collectors.toList());
                this.saveUserRole(param.getUserId(), roleIdList);
            }

            //更新包括更新卡
            //判断现在的卡用户信息力是否有该用户
            CardInfoUser cardInfoUser = cardInfoUserService.getOne(new QueryWrapper<CardInfoUser>()
                    .eq(CardInfoUser.COL_USER_ID, param.getUserId()));

            if (cardInfoUser != null) {
                //如果不是，就生成
                //根据userInfo查询身份
                Integer identityId = param.getIdentityId();
                if (identityId == null) {
                    throw new BusinessException(param.getUserId() + ",该用户身份还未确定,不能领卡");
                }
                CardIdentityRelationInfo cardIdentityRelationInfo = cardIdentityRelationInfoService.getOne(new QueryWrapper<CardIdentityRelationInfo>()
                        .eq(CardIdentityRelationInfo.COL_IDENTITY_ID, identityId));

                if (cardIdentityRelationInfo == null) {
                    throw new BusinessException("该用户身份还未建立对应卡,不能领卡");
                }

                cardInfoUser.setCardId(cardIdentityRelationInfo.getCardId());
                cardInfoUserService.updateById(cardInfoUser);
            }




        }
        return CommRes.ok(param);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean saveOrUpdateSync(SysUserSyncVo param) {

        if (StrUtil.isEmpty(param.getDeptCode())) {
            throw new BusinessException(param.getPhone()+ "请选择部门");
        }

        if (StrUtil.isNotEmpty(param.getDeptCode())){
            //通过deptcode查询deptid
            SysDept sysDept = deptService.getOne(new QueryWrapper<SysDept>().eq(SysDept.COL_CODE, param.getDeptCode()));
            param.setDeptId(sysDept.getDeptId());
            param.setDeptName(sysDept.getDeptName());

        }

        //todo 太多人没有电话号码，先取消限制
//            if (StrUtil.isEmpty(param.getPhone())){
//                throw new BusinessException("必填参数电话号码不能为空");
//            }

        int judge = 0;
        SysUser updateUser = null;
        if (StrUtil.isNotEmpty(param.getUserCode())){
            judge = this.count(new QueryWrapper<SysUser>()
                    .eq(SysUser.COL_USER_CODE, param.getUserCode())
                    .eq(SysUser.COL_DEL_FLAG,0));

            updateUser = this.getOne(new QueryWrapper<SysUser>()
                    .eq(SysUser.COL_USER_CODE, param.getUserCode())
                    .eq(SysUser.COL_DEL_FLAG,0));
        }else {
            judge = this.count(new QueryWrapper<SysUser>()
                    .eq(SysUser.COL_PHONE, param.getPhone())
                    .eq(SysUser.COL_DEL_FLAG,0));

            updateUser = this.getOne(new QueryWrapper<SysUser>()
                    .eq(SysUser.COL_PHONE, param.getPhone())
                    .eq(SysUser.COL_DEL_FLAG,0));
        }

        if (judge <= 0) {
            // 只有超级管理员才能创建用户
            String password = param.getPassword();
            param.setPassword(SecureUtil.sha256(password));
            param.setCreateTime(new Date());
            if (StrUtil.isEmpty(param.getUserCode())){
                param.setUserCode(param.getPhone());
            }

            if (StrUtil.isEmpty(param.getUserName())){
                param.setUserName(param.getPhone());
            }


            //查询根据部门id查询部门信息
            //查询出当前学校的信息
            List<SysSchoolInfo> schoolInfoList = schoolInfoService.list(new QueryWrapper<SysSchoolInfo>().eq(SysSchoolInfo.COL_DEL_FLAG,0));
            if (schoolInfoList.size() > 0){
                SysSchoolInfo schoolInfo = schoolInfoList.get(0);
                param.setSchoolId(schoolInfo.getId());
                param.setSchoolName(schoolInfo.getName());
                param.setSchoolCode(schoolInfo.getSchoolCode());
            }

            SysUser user = new SysUser();
            BeanUtil.copyProperties(param,user);
            this.save(user);

        } else {
            param.setUserId(updateUser.getUserId());

            if (StrUtil.isNotEmpty(param.getPassword())){
                String password = param.getPassword();
                param.setPassword(SecureUtil.sha256(password));
            }


            // 特殊处理电话号码不为空的情况
            if (!updateUser.getPhone().equals(param.getPhone())){
                //当其不相等的时候，将手机号码换为新的手机号码的同时，并且去掉原号的微信小程序openId
                param.setMipOpenId("");
                param.setOpenIdAdmin("");
                param.setPublicOpenId("");
            }



            SysUser user = new SysUser();
            BeanUtil.copyProperties(param,user);
            this.updateById(user);


            //更新包括更新卡
            //判断现在的卡用户信息力是否有该用户
            CardInfoUser cardInfoUser = cardInfoUserService.getOne(new QueryWrapper<CardInfoUser>()
                    .eq(CardInfoUser.COL_USER_ID, param.getUserId()));

            if (cardInfoUser != null) {
                //如果不是，就生成
                //根据userInfo查询身份
                Integer identityId = param.getIdentityId();
                if (identityId == null) {
                    throw new BusinessException(param.getPhone() + ",该用户身份还未确定,不能领卡");
                }
                CardIdentityRelationInfo cardIdentityRelationInfo = cardIdentityRelationInfoService.getOne(new QueryWrapper<CardIdentityRelationInfo>()
                        .eq(CardIdentityRelationInfo.COL_IDENTITY_ID, identityId));

                if (cardIdentityRelationInfo == null) {
                    throw new BusinessException(param.getPhone()+ "该用户身份还未建立对应卡,不能领卡");
                }

                cardInfoUser.setCardId(cardIdentityRelationInfo.getCardId());
                cardInfoUserService.updateById(cardInfoUser);
            }




        }
        return true;
    }

    public boolean saveUserRole(Long userId, List<Integer> roleIds) {
        sysUserRoleService.remove(Wrappers.<SysUserRole>lambdaQuery().eq(SysUserRole::getUserId, userId));

        List<SysUserRole> sysUserRoles = new ArrayList<>();
        roleIds.forEach(roleId -> {
            SysUserRole sysUserRole = new SysUserRole();
            sysUserRole.setRoleId(Long.valueOf(roleId));
            sysUserRole.setUserId(userId);
            sysUserRoles.add(sysUserRole);
        });
        return sysUserRoleService.saveBatch(sysUserRoles);
    }


    /**
     * 通过deptIdList得到用户list
     */
    @Override
    public List<SysUser> getUserByDeptAndSon(Long deptId) {
        List<Long> deptAndSon = this.getDeptAndSon(deptId);
        QueryWrapper<SysUser> wrapper = new QueryWrapper<>();
        if (deptAndSon.size() > 0) {
            wrapper.in(SysUser.COL_DEPT_ID, deptAndSon);
            wrapper.eq(SysUser.COL_DEL_FLAG, 0);
            return this.list(wrapper);
        }

        return new ArrayList<>();

    }

    /**
     * 获得当前用户身份的所有应用
     * @return
     */
    @Override
    public List<ApplicationManagement> getApplicationListByCurrentUserIdentfify() {
        SysUser userInfo = LoginUtil.getUserInfo();

        List<ApplicationManagement> applicationManagementList = sysUserMapper.getApplicationListByCurrentUserIdentfify(userInfo.getIdentityId());

        return applicationManagementList;
    }


    /**
     * 通过递归获得子类deptId
     */
    @Override
    public List<Long> getDeptAndSon(Long deptId) {
        List<Long> deptIdList = new ArrayList<>();

        List<SysDept> deptList = deptService.list();

        deptIdList.add(deptId);
        recursiveDept(deptIdList, deptList, deptId);
        return deptIdList;
    }

    /**
     * 获得该deptCode以下所有的deptCode
     *
     * @param DeptCode
     * @return
     */
    @Override
    public List<String> getDeptAndSonByDeptCode(String DeptCode) {
        List<String> deptCodeList = new ArrayList<>();

        List<SysDept> deptList = deptService.list();
        deptCodeList.add(DeptCode);

        recursiveDeptByDeptCode(deptCodeList, deptList, DeptCode);
        return deptCodeList;
    }

    /**
     * 获得DeptCodeList下所有的DeptCode
     * @param DeptCodeList
     * @return
     */
    @Override
    public List<String> getDeptAndSonAsListByDeptCodeList(List<String> DeptCodeList){
        List<String> resultDeptCodeList = new ArrayList<>();
        resultDeptCodeList.addAll(DeptCodeList);

        List<SysDept> deptList = deptService.list();
        for (String deptCode:DeptCodeList){
            recursiveDeptByDeptCode(resultDeptCodeList,deptList,deptCode);
        }
        return resultDeptCodeList;
    }

    /**
     * 通过递归获得子类deptId
     */
    @Override
    public List<Long> getDeptAndSonExcludeOwn(Long deptId) {
        List<Long> deptIdList = new ArrayList<>();

        List<SysDept> deptList = deptService.list();

        recursiveDept(deptIdList, deptList, deptId);
        return deptIdList;
    }

    @Override
    public List<String> getDeptAndSonExcludeOwnByDeptCode(String DeptCode) {
        List<String> deptCodeList = new ArrayList<>();

        List<SysDept> deptList = deptService.list();

        recursiveDeptByDeptCode(deptCodeList, deptList, DeptCode);
        return deptCodeList;
    }

    /**
     * 递归方法
     *
     * @param deptIdList：存储deptId的list
     * @param deptList：所有的dept情况
     * @param deptId：父级deptId
     */
    public void recursiveDept(List<Long> deptIdList, List<SysDept> deptList, Long deptId) {
        for (SysDept oneDept : deptList) {
            if (oneDept.getPid().equals(deptId)) {
                deptIdList.add(oneDept.getDeptId());
                //筛选
                //设定结束界限

                recursiveDept(deptIdList, deptList, oneDept.getDeptId());

            }
        }
    }

    public void recursiveDeptByDeptCode(List<String> deptCodeList, List<SysDept> deptList, String deptCode) {
        for (SysDept oneDept : deptList) {
            if (StrUtil.isNotEmpty(oneDept.getPcode())){
                if (oneDept.getPcode().equals(deptCode)) {
                    deptCodeList.add(oneDept.getCode());
                    //筛选
                    //设定结束界限

                    recursiveDeptByDeptCode(deptCodeList, deptList, oneDept.getCode());

                }
            }

        }
    }


//    public void recursiveDeptAsListByDeptCodeList(List<String> deptCodeList, List<SysDept> deptList, String deptCode) {
//        for (SysDept oneDept : deptList) {
//            if (oneDept.getPcode().equals(deptCode)) {
//                deptCodeList.add(oneDept.getCode());
//                //筛选
//                //设定结束界限
//
//                recursiveDeptAsListByDeptCodeList(deptCodeList, deptList, oneDept.getCode());
//
//            }
//        }
//    }
}





